package com.ruoyi.cm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.ruoyi.base.domain.BaseStandardSheet;
import com.ruoyi.base.domain.BaseStandardTenderSheet;
import com.ruoyi.base.mapper.BaseStandardSheetMapper;
import com.ruoyi.base.mapper.BaseStandardTenderSheetMapper;
import com.ruoyi.cm.domain.*;
import com.ruoyi.cm.domain.bo.CmBdQsCountBo;
import com.ruoyi.cm.domain.bo.CmBsContractInfoBo;
import com.ruoyi.cm.domain.bo.CmBsQsBo;
import com.ruoyi.cm.domain.vo.CmBdQsCountVo;
import com.ruoyi.cm.domain.vo.CmBsContractInfoVo;
import com.ruoyi.cm.domain.vo.PeriodMeasurementVo;
import com.ruoyi.cm.mapper.*;
import com.ruoyi.cm.service.ICmBdQsCountService;
import com.ruoyi.cm.service.ICmBsContractInfoService;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.BigDecimalUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.springframework.stereotype.Service;
import com.ruoyi.cm.domain.bo.CmBaContractSheetsBo;
import com.ruoyi.cm.domain.vo.CmBaContractSheetsVo;
import com.ruoyi.cm.service.ICmBaContractSheetsService;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 合同清单详情Service业务层处理
 *
 * @author zyb
 * @date 2024-09-24
 */
@RequiredArgsConstructor
@Service
public class CmBaContractSheetsServiceImpl implements ICmBaContractSheetsService {

    private final CmBaContractSheetsMapper baseMapper;

    private final BaseStandardSheetMapper baseStandardSheetMapper;

    private final CmBdQsCountMapper cmBdQsCountMapper;
    private final CmReportMapper reportMapper;
    private final CmBsQsMapper qsMapper;

    private final ICmBsContractInfoService iCmBsContractInfoService;

    private final CmPeriodMeasurementMapper cmPeriodMeasurementMapper;

    private final String[] numbers = {"一、", "二、", "三、", "四、", "五、", "六、", "七、", "八、", "九、", "十、"};

    private final String[] numbers1 = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十"};
    private final TaskService taskService;

    /**
     * 查询合同清单详情
     */
    @Override
    public CmBaContractSheetsVo queryById(Long sheetId){
        return baseMapper.selectVoById(sheetId);
    }

    /**
     * 查询合同清单详情列表
     */
    @Override
    public TableDataInfo<CmBaContractSheetsVo> queryPageList(CmBaContractSheetsBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<CmBaContractSheets> lqw = buildQueryWrapper(bo);
        Page<CmBaContractSheetsVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询合同清单详情列表
     */
    @Override
    public Map<String,Object> queryList(CmBaContractSheetsBo bo) {
        Map<String,Object> map = new HashMap<>();
        if (ObjectUtils.isNotEmpty(bo.getBdId()) || ObjectUtils.isNotEmpty(bo.getZdId())){
            LambdaQueryWrapper<CmBaContractSheets> lqw = buildQueryWrapper(bo);
            List<CmBaContractSheetsVo> cmBaContractSheetsVos = baseMapper.selectVoList(lqw);
            if (CollectionUtils.isNotEmpty(cmBaContractSheetsVos)){
                List<BaseStandardSheet> baseStandardSheetList = baseStandardSheetMapper.selectList();
                cmBaContractSheetsVos.forEach(t ->{
                    if (ObjectUtils.isEmpty(t.getChgRongliang())) {
                        t.setChgRongliang(BigDecimal.ZERO);
                    }
                    if (ObjectUtils.isEmpty(t.getChgZongjia())) {
                        t.setChgZongjia(t.getInitZongjia());
                    }
                    BaseStandardSheet baseStandardSheet = baseStandardSheetList.stream().filter(e -> e.getSheetId().equals(t.getStandardId())).findFirst().orElse(null);
                    if (ObjectUtils.isNotEmpty(baseStandardSheet)){
                        t.setSheetTypeName(baseStandardSheet.getSheetName());
                        t.setSheetTypeCode(baseStandardSheet.getSheetCode());
                        t.setSheetFeaturesName(baseStandardSheet.getSpecificationName());
                        t.setSheetUnit(baseStandardSheet.getSheetUnit());
                        t.setSheetTaxRate(baseStandardSheet.getSheetTaxRate());
                        t.setSheetLevel(baseStandardSheet.getSheetLevel());
                    }

//                    if (!"1".equals(t.getSheetLevel()) && ObjectUtils.isNotEmpty(t.getInitDanjia())){
//                        t.setInitDanjia(t.getInitDanjia().setScale(2,BigDecimal.ROUND_HALF_UP));
//                    }
                });
//                // @TODO 暂时添加查询并更新历史纪录的操作,后面删除
//                List<CmBaContractSheets> updateList = BeanUtil.copyToList(cmBaContractSheetsVos, CmBaContractSheets.class);
//                baseMapper.updateBatchById(updateList);
                //判断是否有第一类别的添加
                for (CmBaContractSheetsVo vo : cmBaContractSheetsVos){
                    if("001".equals(vo.getSheetTypeCode().substring(0,3))){
                        CmBaContractSheetsVo cmBaContractSheetsVo = new CmBaContractSheetsVo();
                        BaseStandardSheet baseStandardSheet = baseStandardSheetList.stream().filter(e -> "001".equals(e.getSheetCode())).findFirst().orElse(null);
                        cmBaContractSheetsVo.setSheetTypeName(baseStandardSheet.getSheetName());
                        cmBaContractSheetsVo.setSheetTypeCode(baseStandardSheet.getSheetCode());
                        cmBaContractSheetsVo.setApprovalStatus(vo.getApprovalStatus());
                        cmBaContractSheetsVos.add(cmBaContractSheetsVo);
                        break;
                    }
                }
                //按照编号排序
                Collections.sort(cmBaContractSheetsVos, new Comparator<CmBaContractSheetsVo>() {
                    @Override
                    public int compare(CmBaContractSheetsVo t1, CmBaContractSheetsVo t2) {
                        if (StringUtils.isBlank(t1.getSheetTypeCode()) && StringUtils.isBlank(t2.getSheetTypeCode()) ) {
                            return 0;
                        }
                        if (StringUtils.isBlank(t1.getSheetTypeCode())) {
                            return -1;
                        }
                        if (StringUtils.isBlank(t2.getSheetTypeCode())) {
                            return 1;
                        }
                        return t1.getSheetTypeCode().compareTo(t2.getSheetTypeCode());
                    }
                });

                //添加序号
                int i=0;//大序号
                int j=1;//小序号
                String Code = null;//大序号标识
                String code = null;//小序号标识
                for(CmBaContractSheetsVo vo : cmBaContractSheetsVos){
                    int length = vo.getSheetTypeCode().length();
                    if (length==3){
                        if (!vo.getSheetTypeCode().equals(Code)){
                            String number = numbers[i];
                            vo.setVuhao(number);
                            i++;
                        }else {
                            String number = numbers[i-1];
                            vo.setVuhao(number);
                        }
                        Code = vo.getSheetTypeCode();
                        j=1;
                    }else {
                        if (!vo.getSheetTypeCode().equals(code)){
                            vo.setVuhao(String.valueOf(j));
                            j++;
                        }else {
                            vo.setVuhao(String.valueOf(j-1));
                        }
                        code = vo.getSheetTypeCode();
                    }
                }
                // 设置对应的任务信息
                if(CollUtil.isNotEmpty(cmBaContractSheetsVos)&&cmBaContractSheetsVos.size()>=2){
                    CmBaContractSheetsVo item = cmBaContractSheetsVos.get(1);
                    if (ObjectUtils.isNotEmpty(item.getProInsId())) {
                        List<Task> taskList = taskService.createTaskQuery().processInstanceId(item.getProInsId()).list();
                        if (CollUtil.isNotEmpty(taskList)) {
                            List<Task> sortList = taskList.stream().sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime())).collect(Collectors.toList());
                            Task task = sortList.get(0);
                            item.setTaskId(task.getId());
                            item.setCurrName(task.getName());
                            if (task.getAssignee() != null && (Long.valueOf(task.getAssignee()) == LoginHelper.getUserId())) {
                                item.setCurrApproval(true);
                            } else {
                                item.setCurrApproval(false);
                            }
                        }
                    }
                    cmBaContractSheetsVos.set(1,item);
                }
                map.put("cmBaContractSheetsVos",cmBaContractSheetsVos);

                //总计
                BigDecimal rongliangTotal = cmBaContractSheetsVos.stream().map(CmBaContractSheetsVo::getInitRongliang ).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                BigDecimal zongjiaTotal = cmBaContractSheetsVos.stream().map(CmBaContractSheetsVo::getInitZongjia).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                BigDecimal chgRongliangTotal = cmBaContractSheetsVos.stream().map(CmBaContractSheetsVo::getChgRongliang).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                BigDecimal chgZongjiaTotal = cmBaContractSheetsVos.stream().map(CmBaContractSheetsVo::getChgZongjia).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                Map<String,Object> map1 = new HashMap<>();
                map1.put("rongliangTotal",rongliangTotal);
                map1.put("zongjiaTotal",zongjiaTotal);
                map1.put("chgRongliangTotal",chgRongliangTotal);
                map1.put("chgZongjiaTotal",chgZongjiaTotal);
                map.put("total",map1);
            }

        }
       return map;
    }

    @Override
    public List<CmBaContractSheetsVo> selectList(CmBaContractSheetsBo bo) {
        LambdaQueryWrapper<CmBaContractSheets> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }


    private LambdaQueryWrapper<CmBaContractSheets> buildQueryWrapper(CmBaContractSheetsBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<CmBaContractSheets> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getContractId() != null, CmBaContractSheets::getContractId, bo.getContractId());
        lqw.eq(bo.getBdId() != null, CmBaContractSheets::getBdId, bo.getBdId());
        lqw.eq(bo.getZdId() != null, CmBaContractSheets::getZdId, bo.getZdId());
        lqw.eq(bo.getStandardId() != null, CmBaContractSheets::getStandardId, bo.getStandardId());
        lqw.eq(bo.getInitZongjia() != null, CmBaContractSheets::getInitZongjia, bo.getInitZongjia());
        lqw.eq(bo.getInitRongliang() != null, CmBaContractSheets::getInitRongliang, bo.getInitRongliang());
        lqw.eq(bo.getChgZongjia() != null, CmBaContractSheets::getChgZongjia, bo.getChgZongjia());
        lqw.eq(bo.getChgRongliang() != null, CmBaContractSheets::getChgRongliang, bo.getChgRongliang());
        lqw.eq(bo.getInitDanjia() != null, CmBaContractSheets::getInitDanjia, bo.getInitDanjia());
        lqw.eq(bo.getInitShui() != null, CmBaContractSheets::getInitShui, bo.getInitShui());
        lqw.eq(bo.getLjbgZongjia() != null, CmBaContractSheets::getLjbgZongjia, bo.getLjbgZongjia());
        lqw.eq(bo.getLjbgRongliang() != null, CmBaContractSheets::getLjbgRongliang, bo.getLjbgRongliang());
        lqw.eq(bo.getLjbgDanjia() != null, CmBaContractSheets::getLjbgDanjia, bo.getLjbgDanjia());
        lqw.eq(bo.getLjbgShui() != null, CmBaContractSheets::getLjbgShui, bo.getLjbgShui());
        lqw.eq(bo.getFactZongjia() != null, CmBaContractSheets::getFactZongjia, bo.getFactZongjia());
        lqw.eq(bo.getFactRongliang() != null, CmBaContractSheets::getFactRongliang, bo.getFactRongliang());
        lqw.eq(bo.getFactDanjia() != null, CmBaContractSheets::getFactDanjia, bo.getFactDanjia());
        lqw.eq(bo.getFactShui() != null, CmBaContractSheets::getFactShui, bo.getFactShui());
        lqw.eq(bo.getFactWcrl() != null, CmBaContractSheets::getFactWcrl, bo.getFactWcrl());
        lqw.eq(bo.getFactWczj() != null, CmBaContractSheets::getFactWczj, bo.getFactWczj());
        lqw.eq(bo.getFactZfyfk() != null, CmBaContractSheets::getFactZfyfk, bo.getFactZfyfk());
        lqw.eq(bo.getFactKcyfk() != null, CmBaContractSheets::getFactKcyfk, bo.getFactKcyfk());
        lqw.eq(bo.getFactKk() != null, CmBaContractSheets::getFactKk, bo.getFactKk());
        lqw.eq(bo.getFactFkbl() != null, CmBaContractSheets::getFactFkbl, bo.getFactFkbl());
        lqw.eq(bo.getFactFk() != null, CmBaContractSheets::getFactFk, bo.getFactFk());
        lqw.eq(StringUtils.isNotBlank(bo.getApprovalStatus()), CmBaContractSheets::getApprovalStatus, bo.getApprovalStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getChgApprovalStatus()), CmBaContractSheets::getChgApprovalStatus, bo.getChgApprovalStatus());
        return lqw;
    }

    /**
     * 新增合同清单详情
     */
    @Override
    public Boolean insertByBo(CmBaContractSheetsBo bo) {
        CmBaContractSheets add = BeanUtil.toBean(bo, CmBaContractSheets.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setSheetId(add.getSheetId());
        }
        return flag;
    }

    @Override
    public Boolean insertBatchByBo(List<CmBaContractSheetsBo> boList) {
        List<CmBaContractSheets> cmBaContractSheets = BeanUtil.copyToList(boList, CmBaContractSheets.class);
        cmBaContractSheets.forEach(t->{
            t.setChgZongjia(t.getInitZongjia());
            List<CmBaContractSheetsVo> cmBaContractSheetsVos = baseMapper.selectVoList(new LambdaQueryWrapper<CmBaContractSheets>()
                .eq(t.getBdId() != null, CmBaContractSheets::getBdId, t.getBdId())
                .eq(t.getZdId() != null, CmBaContractSheets::getZdId, t.getZdId())
                .eq(t.getStandardId() != null, CmBaContractSheets::getStandardId, t.getStandardId()));
            if (ObjectUtils.isEmpty(cmBaContractSheetsVos)){
                baseMapper.insert(t);
            }
        });
        return true;
    }

    /*
     * 修改合同清单详情
     */
    @Override
    public Boolean updateByBo(CmBaContractSheetsBo bo) {
        CmBaContractSheets update = BeanUtil.toBean(bo, CmBaContractSheets.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    @Override
    @DSTransactional
    public Boolean editBatch(List<CmBaContractSheetsBo> boList) {
        List<CmBaContractSheets> cmBaContractSheets = BeanUtil.copyToList(boList, CmBaContractSheets.class);
//        sheetid,bdid,zdid
//        contractListId,bdid,zdid
        //同步变更数量到中间计量表中；
        if(CollUtil.isNotEmpty(boList)){
            CmBaContractSheetsBo sheetsBo = boList.get(1);
            Long bdId = sheetsBo.getBdId();
            Long zdId = sheetsBo.getZdId();
            List<CmBsQs> qsList = qsMapper.selectList(new LambdaQueryWrapper<CmBsQs>().in(CmBsQs::getBdId,bdId));
            Set<Long> qsIds = qsList.stream().map(CmBsQs::getQsId).collect(Collectors.toSet());
            List<CmPeriodMeasurement> measurements = cmPeriodMeasurementMapper.selectList(new LambdaQueryWrapper<CmPeriodMeasurement>()
                .eq(CmPeriodMeasurement::getBdId,bdId).eq(CmPeriodMeasurement::getZdId,zdId).in(CmPeriodMeasurement::getQsId,qsIds));
            //查询报表管理各期次的审批状态，状态为已审批“22”和审批中“11”的不处理，
            List<CmReport> cmReports = reportMapper.selectList(new LambdaQueryWrapper<CmReport>().eq(CmReport::getBdId,bdId));
            Map<Long, String> reportStatusMap = cmReports.stream().filter(e->e.getZdId() == null).collect(Collectors.toMap(CmReport::getQsId, CmReport::getStatus));
            //找出需要同步的中间计量列表；
            List<CmPeriodMeasurement> editMeasurements;
            if(CollUtil.isEmpty(cmReports)){
                editMeasurements = measurements;
            }else{
                //过滤掉审批中、已审批的中间计量数据；
                editMeasurements = measurements.stream().filter(e->"00".equals(reportStatusMap.get(e.getQsId()))||"33".equals(reportStatusMap.get(e.getQsId()))).collect(Collectors.toList());
            }
            //处理需要同步的中间计量列表；
            if(CollUtil.isNotEmpty(editMeasurements)) {
                Map<Long, List<CmPeriodMeasurement>> measurementMaps = measurements.stream().collect(Collectors.groupingBy(CmPeriodMeasurement::getContractListId));
                Map<Long, CmBaContractSheets> sheetsMap = cmBaContractSheets.stream().collect(Collectors.toMap(CmBaContractSheets::getSheetId, e -> e));
                for (CmPeriodMeasurement pm : editMeasurements) {
                    CmBaContractSheets contractSheets = sheetsMap.get(pm.getContractListId());
                    //计算所有期次的计量之和；
                    List<CmPeriodMeasurement> measurements1 = measurementMaps.get(pm.getContractListId());
                    BigDecimal totalmq = BigDecimal.ZERO;
                    if (CollUtil.isNotEmpty(measurements1)) {
                        for (CmPeriodMeasurement e : measurements1) {
                            totalmq = BigDecimalUtil.add(totalmq, e.getMeasurementQuantity() == null ? BigDecimal.ZERO : e.getMeasurementQuantity());
                        }
                    }
                    //需要更新变更容量、变更后总价，未计量数量字段；
                    BigDecimal chgrl = contractSheets == null ? BigDecimal.ZERO : contractSheets.getChgRongliang();
                    BigDecimal initrl = contractSheets == null ? BigDecimal.ZERO : contractSheets.getInitRongliang();
                    pm.setRemainingQuantity(BigDecimalUtil.subtract(BigDecimalUtil.add(chgrl == null ? BigDecimal.ZERO : chgrl, initrl == null ? BigDecimal.ZERO : initrl), totalmq));
                }
                cmPeriodMeasurementMapper.updateBatchById(editMeasurements);
            }
        }
        return baseMapper.updateBatchById(cmBaContractSheets);
    }

    /*
     * 修改合同清单详情审批状态
     */
    @Override
    public Boolean updateApprovalStatusByBo(CmBaContractSheetsBo bo) {
        LambdaUpdateWrapper<CmBaContractSheets> lambdaUpdateWrapper = new LambdaUpdateWrapper();
        lambdaUpdateWrapper.set(ObjectUtils.isNotEmpty(bo.getApprovalStatus()), CmBaContractSheets :: getApprovalStatus,bo.getApprovalStatus());
        lambdaUpdateWrapper.set(ObjectUtils.isNotEmpty(bo.getChgApprovalStatus()), CmBaContractSheets :: getChgApprovalStatus,bo.getChgApprovalStatus());
        lambdaUpdateWrapper.set(bo.getProInsId() != null, CmBaContractSheets::getProInsId, bo.getProInsId());
        lambdaUpdateWrapper.eq(bo.getBdId() != null, CmBaContractSheets :: getBdId,bo.getBdId());
        lambdaUpdateWrapper.eq(bo.getZdId() != null, CmBaContractSheets::getZdId, bo.getZdId());
        return baseMapper.update(null,lambdaUpdateWrapper)>0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(CmBaContractSheets entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除合同清单详情
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public Map<String, Object> listBillingInfo(String bdId,String zdId) {
        Map<String,Object> map = new HashMap<>();
        if (ObjectUtils.isNotEmpty(bdId) || ObjectUtils.isNotEmpty(zdId)){
            //查询合同清单和标准清单
            List<CmBaContractSheetsVo> cmBaContractSheetsVos = baseMapper.selectContractDataList(bdId,zdId);
            if (CollectionUtils.isNotEmpty(cmBaContractSheetsVos)){
                for (CmBaContractSheetsVo cmBaContractSheetsVo :cmBaContractSheetsVos ){
                    String sheetId = String.valueOf(cmBaContractSheetsVo.getSheetId());
                    //查询中间计量
                    List<PeriodMeasurementVo> voList = baseMapper.selectMeasurementDataList(bdId,zdId,sheetId);
                    cmBaContractSheetsVo.setPeriodMeasurementVoList(voList);

                    if (!"1".equals(cmBaContractSheetsVo.getSheetLevel()) && ObjectUtils.isNotEmpty(cmBaContractSheetsVo.getInitDanjia())){
                        cmBaContractSheetsVo.setInitDanjia(cmBaContractSheetsVo.getInitDanjia().setScale(2,BigDecimal.ROUND_HALF_UP));
                    }
                }
                List<BaseStandardSheet> baseStandardSheetList = baseStandardSheetMapper.selectList();
                //判断是否有第一类别的添加
                for (CmBaContractSheetsVo vo : cmBaContractSheetsVos){
                    if("001".equals(vo.getSheetTypeCode().substring(0,3))){
                        CmBaContractSheetsVo cmBaContractSheetsVo = new CmBaContractSheetsVo();
                        BaseStandardSheet baseStandardSheet = baseStandardSheetList.stream().filter(e -> "001".equals(e.getSheetCode())).findFirst().orElse(null);
                        cmBaContractSheetsVo.setSheetTypeName(baseStandardSheet.getSheetName());
                        cmBaContractSheetsVo.setSheetTypeCode(baseStandardSheet.getSheetCode());
                        String sheetId = String.valueOf(vo.getSheetId());
                        List<PeriodMeasurementVo> voList = baseMapper.selectMeasurementDataListCount(bdId, zdId, sheetId);
                        cmBaContractSheetsVo.setPeriodMeasurementVoList(voList);
                        cmBaContractSheetsVos.add(cmBaContractSheetsVo);
                        break;
                    }
                }
                //按照编号排序
                Collections.sort(cmBaContractSheetsVos, new Comparator<CmBaContractSheetsVo>() {
                    @Override
                    public int compare(CmBaContractSheetsVo t1, CmBaContractSheetsVo t2) {
                        return t1.getSheetTypeCode().compareTo(t2.getSheetTypeCode());
                    }
                });

                //添加序号
                int i=0;//大序号
                int j=1;//小序号
                String Code = null;//大序号标识
                String code = null;//小序号标识
                for(CmBaContractSheetsVo vo : cmBaContractSheetsVos){
                    int length = vo.getSheetTypeCode().length();
                    if (length==3){
                        if (!vo.getSheetTypeCode().equals(Code)){
                            String number = numbers[i];
                            vo.setVuhao(number);
                            i++;
                        }else {
                            String number = numbers[i-1];
                            vo.setVuhao(number);
                        }
                        Code = vo.getSheetTypeCode();
                        j=1;
                    }else {
                        if (!vo.getSheetTypeCode().equals(code)){
                            vo.setVuhao(String.valueOf(j));
                            j++;
                        }else {
                            vo.setVuhao(String.valueOf(j-1));
                        }
                        code = vo.getSheetTypeCode();
                    }
                }

                //查询支付比列,期数id
                List<Map<String,Object>> mapList = baseMapper.selcetFkblList(bdId,zdId);
                List<Map<String, Object>> resultHeaderList = new ArrayList<>();

                //根据标段、站点、期数获取本期支付，累计支付
                List<CmBdQsCount> cmBdQsCountList = new ArrayList<>();
                for(Map<String,Object> fkbl : mapList){
                    Map<String, Object> resultHeaderMap = new HashMap<>();
                    resultHeaderMap.put("kp",fkbl.get("settleIndex"));
                    resultHeaderMap.put("bl",fkbl.get("kgyfkbl"));
                    resultHeaderList.add(resultHeaderMap);
                    CmBdQsCount cmBdQsCount = baseMapper.selectBdQsCount(bdId,zdId, String.valueOf(fkbl.get("qsId")));
                    if(ObjectUtils.isEmpty(cmBdQsCount)){
                        CmBdQsCount cmBdQsCount1 = new CmBdQsCount();
                        cmBdQsCount1.setBdId(Long.valueOf(bdId));
                        cmBdQsCountList.add(cmBdQsCount1);
                    }else {
                        cmBdQsCountList.add(cmBdQsCount);
                    }
                }

                //转为一层
                List<Map<String, Object>> result = new ArrayList<>();
                for (CmBaContractSheetsVo  vo: cmBaContractSheetsVos){
                    Map<String, Object> resultMap = new HashMap<>();
                    resultMap.put("sheetId",vo.getSheetId());
                    resultMap.put("vuhao",vo.getVuhao());
                    resultMap.put("sheetTypeName",vo.getSheetTypeName());
                    resultMap.put("sheetFeaturesName",vo.getSheetFeaturesName());
                    resultMap.put("initDanjia",vo.getInitDanjia());
                    resultMap.put("initRongliang",vo.getInitRongliang());
                    resultMap.put("initZongjia",vo.getInitZongjia());
                    resultMap.put("initZongjiaSum",vo.getInitZongjiaSum());
                    resultMap.put("sheetUnit",vo.getSheetUnit());
                    resultMap.put("sheetTaxRate",vo.getSheetTaxRate());
                    resultMap.put("sheetLevel",vo.getSheetLevel());

                    BigDecimal ljkpje = BigDecimal.ZERO;
                    for (int s=0; s<vo.getPeriodMeasurementVoList().size();s++){
                        Map<String, PeriodMeasurementVo> collect = vo.getPeriodMeasurementVoList().stream().collect(Collectors.toMap(PeriodMeasurementVo::getSettleIndex, e -> e,(e1,e2)->e1));
                        PeriodMeasurementVo periodMeasurementVo = collect.get(s+1+"");
                        resultMap.put("measurementQuantity"+(s+1),periodMeasurementVo == null ? null : periodMeasurementVo.getMeasurementQuantity());
                        resultMap.put("totalPrice"+(s+1),periodMeasurementVo == null ? null : periodMeasurementVo.getTotalPrice());
                        if (s<=cmBdQsCountList.size()-1) {
                            if (ObjectUtils.isNotEmpty(cmBdQsCountList.get(s))) {
                                if (ObjectUtils.isNotEmpty(cmBdQsCountList.get(s).getBqzfje())){
                                    resultMap.put("bqzfje"+(s+1),cmBdQsCountList.get(s).getBqzfje());
                                } else {
                                    resultMap.put("bqzfje"+(s+1),BigDecimal.ZERO);
                                }
                            } else {
                                resultMap.put("bqzfje"+(s+1),BigDecimal.ZERO);
                            }
                        } else {
                            resultMap.put("bqzfje"+(s+1),BigDecimal.ZERO);
                        }

                        if (s<=resultHeaderList.size()-1) {
                            if (ObjectUtils.isNotEmpty(resultHeaderList.get(s))) {
                                resultHeaderList.get(s).put("sl","measurementQuantity"+(s+1));
                                resultHeaderList.get(s).put("kpje","totalPrice"+(s+1));
                                resultHeaderList.get(s).put("bqzfje","bqzfje"+(s+1));
                            }
                        }
//                        resultMap.put("bqzfje"+(s+1),cmBdQsCountList.get(s).getBqzfje());
//                        resultHeaderList.get(s).put("sl","measurementQuantity"+(s+1));
//                        resultHeaderList.get(s).put("kpje","totalPrice"+(s+1));
//                        resultHeaderList.get(s).put("bqzfje","bqzfje"+(s+1));
                        if (periodMeasurementVo!=null && ObjectUtils.isNotEmpty(periodMeasurementVo.getTotalPrice())) {
                            BigDecimal de = new BigDecimal(periodMeasurementVo.getTotalPrice());
                            ljkpje = ljkpje.add(de);
                        }
                    }

                    // 历次累计开票金额合计 / 总价 = 占比
                    BigDecimal ratio = BigDecimal.ZERO;
                    if (ObjectUtils.isNotEmpty(vo.getInitZongjia()) && vo.getInitZongjia().compareTo(BigDecimal.ZERO) > 0) {
                        ratio = ljkpje.divide(vo.getInitZongjia(), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
                    }
                    resultMap.put("ratio", ratio);

                    result.add(resultMap);
                }

                map.put("result",result);
                map.put("resultHeader",resultHeaderList);


                //总计
                BigDecimal rongliangTotal = cmBaContractSheetsVos.stream().map(CmBaContractSheetsVo::getInitRongliang ).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                BigDecimal zongjiaTotal = cmBaContractSheetsVos.stream().map(CmBaContractSheetsVo::getInitZongjia).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
//                BigDecimal chgRongliangTotal = cmBaContractSheetsVos.stream().map(CmBaContractSheetsVo::getChgRongliang).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
//                BigDecimal chgZongjiaTotal = cmBaContractSheetsVos.stream().map(CmBaContractSheetsVo::getChgZongjia).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                BigDecimal maxljzfje = cmBdQsCountList.stream().map(CmBdQsCount::getLjzfje).filter(Objects::nonNull).max(BigDecimal::compareTo).orElse(null);

                Map<String,Object> mapTotal = new HashMap<>();
                mapTotal.put("rongliangTotal",rongliangTotal);
                mapTotal.put("zongjiaTotal",zongjiaTotal);
//                mapTotal.put("chgRongliangTotal",chgRongliangTotal);
//                mapTotal.put("chgZongjiaTotal",chgZongjiaTotal);
                mapTotal.put("ljkfje",maxljzfje);

                for (int z=0; z<resultHeaderList.size();z++){
                    Map<String, Object> resultHeader = resultHeaderList.get(z);
                    if (CollectionUtils.isNotEmpty(resultHeader)&&ObjectUtils.isNotEmpty(resultHeader.get("kpje"))){

                        BigDecimal totalPrice =result.stream().map(map1 ->{
                            String kpje = String.valueOf(resultHeader.get("kpje"));
                            BigDecimal bigDecimal = new BigDecimal(ObjectUtils.isEmpty(map1.get(kpje))?"0.0":String.valueOf(map1.get(kpje)));
                            return bigDecimal;
                        })
                            .filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);

                        mapTotal.put("totalPrice"+(z+1),totalPrice.compareTo(new BigDecimal("0.0"))==0?null:totalPrice);
                        mapTotal.put("bqzfje"+(z+1),cmBdQsCountList.get(z).getBqzfje());
                    }
                }
                map.put("total",mapTotal);
            }

        }
        return map;
    }

    @Override
    public Map<String, Object> listBillingInfoExport(String bdId,String zdId) {
        Map<String,Object> map = new HashMap<>();
        if (ObjectUtils.isNotEmpty(bdId) || ObjectUtils.isNotEmpty(zdId)){
            //查询合同清单和标准清单
            List<CmBaContractSheetsVo> cmBaContractSheetsVos = baseMapper.selectContractDataList(bdId,zdId);
            if (CollectionUtils.isNotEmpty(cmBaContractSheetsVos)){
                for (CmBaContractSheetsVo cmBaContractSheetsVo :cmBaContractSheetsVos ){
                    String sheetId = String.valueOf(cmBaContractSheetsVo.getSheetId());
                    //查询中间计量
                    List<PeriodMeasurementVo> voList = baseMapper.selectMeasurementDataList(bdId,zdId,sheetId);
                    cmBaContractSheetsVo.setPeriodMeasurementVoList(voList);

                    if (!"1".equals(cmBaContractSheetsVo.getSheetLevel()) && ObjectUtils.isNotEmpty(cmBaContractSheetsVo.getInitDanjia())){
                        cmBaContractSheetsVo.setInitDanjia(cmBaContractSheetsVo.getInitDanjia().setScale(2,BigDecimal.ROUND_HALF_UP));
                    }
                }
                List<BaseStandardSheet> baseStandardSheetList = baseStandardSheetMapper.selectList();
                //判断是否有第一类别的添加
                for (CmBaContractSheetsVo vo : cmBaContractSheetsVos){
                    if("001".equals(vo.getSheetTypeCode().substring(0,3))){
                        CmBaContractSheetsVo cmBaContractSheetsVo = new CmBaContractSheetsVo();
                        BaseStandardSheet baseStandardSheet = baseStandardSheetList.stream().filter(e -> "001".equals(e.getSheetCode())).findFirst().orElse(null);
                        cmBaContractSheetsVo.setSheetTypeName(baseStandardSheet.getSheetName());
                        cmBaContractSheetsVo.setSheetTypeCode(baseStandardSheet.getSheetCode());
                        String sheetId = String.valueOf(vo.getSheetId());
                        List<PeriodMeasurementVo> voList = baseMapper.selectMeasurementDataListCount(bdId, zdId, sheetId);
                        cmBaContractSheetsVo.setPeriodMeasurementVoList(voList);
                        cmBaContractSheetsVos.add(cmBaContractSheetsVo);
                        break;
                    }
                }
                //按照编号排序
                Collections.sort(cmBaContractSheetsVos, new Comparator<CmBaContractSheetsVo>() {
                    @Override
                    public int compare(CmBaContractSheetsVo t1, CmBaContractSheetsVo t2) {
                        return t1.getSheetTypeCode().compareTo(t2.getSheetTypeCode());
                    }
                });

                //添加序号
                int i=0;//大序号
                int j=1;//小序号
                String Code = null;//大序号标识
                String code = null;//小序号标识
                for(CmBaContractSheetsVo vo : cmBaContractSheetsVos){
                    int length = vo.getSheetTypeCode().length();
                    if (length==3){
                        if (!vo.getSheetTypeCode().equals(Code)){
                            String number = numbers[i];
                            vo.setVuhao(number);
                            i++;
                        }else {
                            String number = numbers[i-1];
                            vo.setVuhao(number);
                        }
                        Code = vo.getSheetTypeCode();
                        j=1;
                    }else {
                        if (!vo.getSheetTypeCode().equals(code)){
                            vo.setVuhao(String.valueOf(j));
                            j++;
                        }else {
                            vo.setVuhao(String.valueOf(j-1));
                        }
                        code = vo.getSheetTypeCode();
                    }
                }

                //查询支付比列,期数id
                List<Map<String,Object>> mapList = baseMapper.selcetFkblList(bdId,zdId);
                List<Map<String, Object>> resultHeaderList = new ArrayList<>();

                List<List<String>> heads = new ArrayList<>();
                heads.add(Arrays.asList("序号", "序号"));
                heads.add(Arrays.asList("类别", "类别"));
                heads.add(Arrays.asList("规格型号", "规格型号"));
                heads.add(Arrays.asList("单位", "单位"));
                heads.add(Arrays.asList("数量", "数量"));
                heads.add(Arrays.asList("单价", "单价"));
                heads.add(Arrays.asList("总价", "总价"));
                heads.add(Arrays.asList("税价合计", "税价合计"));
                heads.add(Arrays.asList("税率(%)", "税率(%)"));

                //根据标段、站点、期数获取本期支付，累计支付
                List<CmBdQsCount> cmBdQsCountList = new ArrayList<>();
                for(int y=0;y<mapList.size();y++){
                    Map<String,Object> fkbl = mapList.get(y);
                    Map<String, Object> resultHeaderMap = new HashMap<>();
                    resultHeaderMap.put("kp",fkbl.get("settleIndex"));
                    resultHeaderMap.put("bl",fkbl.get("kgyfkbl"));

                    heads.add(Arrays.asList("第"+numbers1[y]+"次开发票", "数量"));
                    heads.add(Arrays.asList("第"+numbers1[y]+"次开发票", "开票金额"));
                    heads.add(Arrays.asList("第"+numbers1[y]+"次开发票", "本次付款金额"));

                    resultHeaderList.add(resultHeaderMap);
                    CmBdQsCount cmBdQsCount = baseMapper.selectBdQsCount(bdId,zdId, String.valueOf(fkbl.get("qsId")));
                    if(ObjectUtils.isEmpty(cmBdQsCount)){
                        CmBdQsCount cmBdQsCount1 = new CmBdQsCount();
                        cmBdQsCount1.setBdId(Long.valueOf(bdId));
                        cmBdQsCountList.add(cmBdQsCount1);
                    }else {
                        cmBdQsCountList.add(cmBdQsCount);
                    }
                }

                heads.add(Arrays.asList("累计付款金额", "累计付款金额"));
                map.put("heads",heads);

                //转为一层
                List<Map<String, Object>> result = new ArrayList<>();
                for (CmBaContractSheetsVo  vo: cmBaContractSheetsVos){
                    Map<String, Object> resultMap = new HashMap<>();
                    resultMap.put("sheetId",vo.getSheetId());
                    resultMap.put("vuhao",vo.getVuhao());
                    resultMap.put("sheetTypeName",vo.getSheetTypeName());
                    resultMap.put("sheetFeaturesName",vo.getSheetFeaturesName());
                    resultMap.put("initDanjia",vo.getInitDanjia());
                    resultMap.put("initRongliang",vo.getInitRongliang());
                    resultMap.put("initZongjia",vo.getInitZongjia());
                    resultMap.put("initZongjiaSum",vo.getInitZongjiaSum());
                    resultMap.put("sheetUnit",vo.getSheetUnit());
                    resultMap.put("sheetTaxRate",vo.getSheetTaxRate());
                    resultMap.put("sheetLevel",vo.getSheetLevel());
                    resultMap.put("ljkfje",null);
                    for (int s=0; s<vo.getPeriodMeasurementVoList().size();s++){
                        Map<String, PeriodMeasurementVo> collect = vo.getPeriodMeasurementVoList().stream().collect(Collectors.toMap(PeriodMeasurementVo::getSettleIndex, e -> e));
                        PeriodMeasurementVo periodMeasurementVo = collect.get(s+1+"");
                        resultMap.put("measurementQuantity"+(s+1),periodMeasurementVo.getMeasurementQuantity());
                        resultMap.put("totalPrice"+(s+1),periodMeasurementVo.getTotalPrice());
                        resultMap.put("bqzfje"+(s+1),cmBdQsCountList.get(s).getBqzfje());
                        resultHeaderList.get(s).put("sl","measurementQuantity"+(s+1));
                        resultHeaderList.get(s).put("kpje","totalPrice"+(s+1));
                        resultHeaderList.get(s).put("bqzfje","bqzfje"+(s+1));
                    }
                    result.add(resultMap);
                }

                map.put("result",result);
                map.put("resultHeader",resultHeaderList);


                //总计
                BigDecimal rongliangTotal = cmBaContractSheetsVos.stream().map(CmBaContractSheetsVo::getInitRongliang ).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                BigDecimal zongjiaTotal = cmBaContractSheetsVos.stream().map(CmBaContractSheetsVo::getInitZongjia).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                BigDecimal maxljzfje = cmBdQsCountList.stream().map(CmBdQsCount::getLjzfje).filter(Objects::nonNull).max(BigDecimal::compareTo).orElse(null);

                Map<String,Object> mapTotal = new HashMap<>();
                mapTotal.put("rongliangTotal",rongliangTotal);
                mapTotal.put("zongjiaTotal",zongjiaTotal);
                mapTotal.put("ljkfje",maxljzfje);

                for (int z=0; z<resultHeaderList.size();z++){
                    Map<String, Object> resultHeader = resultHeaderList.get(z);
                    if (CollectionUtils.isNotEmpty(resultHeader)&&ObjectUtils.isNotEmpty(resultHeader.get("kpje"))){

                        BigDecimal totalPrice =result.stream().map(map1 ->{
                            String kpje = String.valueOf(resultHeader.get("kpje"));
                            BigDecimal bigDecimal = new BigDecimal(ObjectUtils.isEmpty(map1.get(kpje))?"0.0":String.valueOf(map1.get(kpje)));
                            return bigDecimal;
                        })
                            .filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);

                        mapTotal.put("totalPrice"+(z+1),totalPrice.compareTo(new BigDecimal("0.0"))==0?null:totalPrice);
                        mapTotal.put("bqzfje"+(z+1),cmBdQsCountList.get(z).getBqzfje());
                    }
                }
                map.put("total",mapTotal);
            }

        }
        return map;
    }

    @Override
    public Map<String, Object> getApprovalStatus(String bdId, String zdId) {
        List<CmBaContractSheetsVo> cmBaContractSheetsVos = baseMapper.selectVoList(new LambdaQueryWrapper<CmBaContractSheets>()
            .eq(bdId != null, CmBaContractSheets::getBdId, bdId)
            .eq(zdId != null, CmBaContractSheets::getZdId, zdId));
        Map<String, Object> data = new HashMap<>();
        String approvalStatus ="00";
        String chgApprovalStatus = "00";
        // 默认值为00
        if (CollectionUtils.isNotEmpty(cmBaContractSheetsVos)){
            String status1 = cmBaContractSheetsVos.get(0).getApprovalStatus();
            String status2 = cmBaContractSheetsVos.get(0).getChgApprovalStatus();
            if (StringUtils.isNotBlank(status1)) {
                approvalStatus = status1;
            }
            if (StringUtils.isNotBlank(status2)) {
                chgApprovalStatus = status2;
            }
        }
        data.put("approvalStatus", approvalStatus);
        data.put("chgApprovalStatus", chgApprovalStatus);
        return data;
    }

    @Override
    public R check(String bdId) {
        CmBaContractSheetsBo bo = new CmBaContractSheetsBo();
        bo.setBdId(Long.valueOf(bdId));
        Map<String, Object> map = this.queryList(bo);
        Map<String, Object> total = (Map<String, Object>) map.get("total");
        CmBsContractInfoBo cmBsContractInfoBo = new CmBsContractInfoBo();
        cmBsContractInfoBo.setBdId(Long.valueOf(bdId));
        List<CmBsContractInfoVo> cmBsContractInfoVos = iCmBsContractInfoService.queryList(cmBsContractInfoBo);
        if (CollectionUtils.isNotEmpty(cmBsContractInfoVos)){
            if (CollectionUtils.isEmpty(total) || ObjectUtils.isEmpty(total.get("zongjiaTotal"))){
                return R.fail("合同清单金额为空");
            }
            if (ObjectUtils.isEmpty(cmBsContractInfoVos.get(0).getContractAmount())){
                return R.fail("合同信息金额为空");
            }
            if (cmBsContractInfoVos.get(0).getContractAmount().compareTo((BigDecimal) total.get("zongjiaTotal"))==0){
                return R.ok();
            }
        }
        return R.fail("该标段合同信息金额与合同清单金额不一致，无法审批");
    }

    // 合同清单批量变更信息保存
    @Override
    public Boolean editChgBatch(List<CmBaContractSheetsBo> boList) {
        List<CmBaContractSheets> cmBaContractSheets = BeanUtil.copyToList(boList, CmBaContractSheets.class);
        cmBaContractSheets.forEach(item -> {
            // 变更数量为0,赋值变更货合计为初始合计
            if (ObjectUtils.isNotEmpty(item.getInitRongliang()) && item.getInitRongliang().compareTo(BigDecimal.ZERO) == 0) {
                if (ObjectUtils.isEmpty(item.getChgZongjia())) {
                    item.setChgZongjia(item.getInitZongjia());
                }
            }
        });
        return baseMapper.updateBatchById(cmBaContractSheets);
    }
}
